package cn.blnp.net.flowable.boot.config;

import cn.blnp.net.flowable.boot.bean.entity.HcTenant;
import cn.blnp.net.flowable.boot.config.flowable.MultiTenantDataSourceProcessConfig;
import cn.blnp.net.flowable.boot.customer.flowable.cache.FlowableSerializable;
import cn.blnp.net.flowable.boot.customer.flowable.holder.MultiTenantInfoHolder;
import cn.blnp.net.flowable.boot.service.ITenantService;
import cn.blnp.net.flowable.boot.utils.TenantContextHolder;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.idm.engine.IdmEngineConfiguration;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

/**
 * <h3>自定义项目相关配置</h3>
 *
 * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
 * @version 1.0
 * @since 2025/6/9 19:35
 */
@Slf4j
@Configuration
@AllArgsConstructor
public class CusItemConfiguration {

    private final ITenantService tenantService;
    private final DataSource dataSource;

    @Bean
    public MultiTenantInfoHolder multiTenantInfoHolder() {
        MultiTenantInfoHolder tenantInfoHolder = new MultiTenantInfoHolder();
        //查询平台内的所有租户信息
        List<HcTenant> tenantListInfo = tenantService.lambdaQuery()
                .list();
        CopyOnWriteArrayList<String> tenantList = new CopyOnWriteArrayList<>();
        for (HcTenant hcTenant : tenantListInfo) {
            if (StringUtils.isBlank(hcTenant.getDataSource())) {
                continue;
            }
            tenantList.add(hcTenant.getId());
        }
        tenantInfoHolder.setTenantList(tenantList);
        return tenantInfoHolder;
    }

    @Bean
    @DependsOn("multiTenantInfoHolder")
    public MultiTenantDataSourceProcessConfig multiTenantDataSourceProcessConfig(MultiTenantInfoHolder multiTenantInfoHolder) {
        MultiTenantDataSourceProcessConfig tenantDataSource = new MultiTenantDataSourceProcessConfig(multiTenantInfoHolder);
        tenantDataSource.setDatabaseType("mysql");
        //平台租户列表信息
        List<HcTenant> tenantListInfo = tenantService.lambdaQuery()
                .list();
        //租户与对应数据源关系
        Map<String, DataSource> tenantRelationMap = new ConcurrentHashMap<>();
        for (HcTenant tenant : tenantListInfo) {
            if (StringUtils.isNotBlank(tenant.getDataSource())) {
                JSONObject dataSourceConfig = JSONUtil.parseObj(tenant.getDataSource());
                //对应租户的数据源配置信息
                DruidDataSource dataSource = new DruidDataSource();
                dataSource.setUrl(dataSourceConfig.getStr("url"));
                dataSource.setUsername(dataSourceConfig.getStr("username"));
                dataSource.setPassword(dataSourceConfig.getStr("password"));
                dataSource.setDriverClassName(dataSourceConfig.getStr("driverClassName"));
                dataSource.setInitialSize(dataSourceConfig.getInt("initialSize",5));
                tenantRelationMap.put(tenant.getId(), dataSource);
            }
        }
        //数据库的执行策略
        tenantDataSource.setDatabaseSchemaUpdate("true");
        tenantDataSource.setDisableEventRegistry(true);
        tenantDataSource.setTenantDataSourceRelationMap(tenantRelationMap);
        return tenantDataSource;
    }

    @Bean
    public CaffeineCacheManager caffeineCacheManager() {
        CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
        //配置缓存参数，最大缓存数1000，超时时间10分钟
        //caffeineCacheManager.setCacheSpecification("maximumSize=1000,expireAfterWrite=10m");
        caffeineCacheManager.setCaffeine(Caffeine.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .maximumSize(1000));
        //限制不缓存空值
        caffeineCacheManager.setAllowNullValues(false);
        return caffeineCacheManager;
    }

    /**
     * <p><b>用途:身份认证配置初始化<b></p>
     * @author <a href="mailto:blnp.yibin@qq.com">lyb</a>
     * @since 17:22 2025/6/12
     * @params [] 
     * @param  
     * @return org.flowable.idm.engine.IdmEngineConfiguration
    **/
    @Bean
    public IdmEngineConfiguration idmEngineConfiguration() {
        IdmEngineConfiguration configuration = new IdmEngineConfiguration();
        return configuration;
    }

    //@Bean
    //public AbstractRoutingDataSource routingDataSource() {
    //    AbstractRoutingDataSource routingDataSource = new AbstractRoutingDataSource() {
    //        @Override
    //        protected Object determineCurrentLookupKey() {
    //            return TenantContextHolder.getTenantId(); // 获取当前租户ID并决定数据源
    //        }
    //    };
    //    Map<Object, Object> targetDataSources = new HashMap<>();
    //    //targetDataSources.putAll(multiTenantDataSourceProcessConfig.getTenantDataSourceRelationMap());
    //    //平台租户列表信息
    //    List<HcTenant> tenantListInfo = tenantService.lambdaQuery()
    //            .list();
    //    for (HcTenant tenant : tenantListInfo) {
    //        if (StringUtils.isNotBlank(tenant.getDataSource())) {
    //            JSONObject dataSourceConfig = JSONUtil.parseObj(tenant.getDataSource());
    //            //对应租户的数据源配置信息
    //            DruidDataSource dataSource = new DruidDataSource();
    //            dataSource.setUrl(dataSourceConfig.getStr("url"));
    //            dataSource.setUsername(dataSourceConfig.getStr("username"));
    //            dataSource.setPassword(dataSourceConfig.getStr("password"));
    //            dataSource.setDriverClassName(dataSourceConfig.getStr("driverClassName"));
    //            dataSource.setInitialSize(dataSourceConfig.getInt("initialSize",5));
    //            targetDataSources.put(tenant.getId(), dataSource);
    //        }
    //    }
    //    // 设置所有可用的数据源及其标识符
    //    routingDataSource.setTargetDataSources(targetDataSources);
    //    // 设置默认数据源，以防万一找不到匹配的租户ID时使用哪个数据源
    //    routingDataSource.setDefaultTargetDataSource(dataSource);
    //    return routingDataSource;
    //}
}
